import pandas as pd
import numpy as np

# 从 CSV 文件读取数据集
file_path = 'wine/wine.data'
columns = ['Class', 'Alcohol', 'Malic_Acid', 'Ash', 'Alcalinity_of_Ash',
           'Magnesium', 'Total_Phenols', 'Flavanoids', 'Nonflavanoid_Phenols',
           'Proanthocyanins', 'Color_Intensity', 'Hue', 'OD280_OD315', 'Proline']
df = pd.read_csv(file_path, header=None, names=columns)

# 数据预处理：将类别标签转为二进制特征
df['Class'] = df['Class'].astype(str)  # 将类别转换为字符串

# 可以选择将某些数值特征离散化（例如使用分位数）
# 示例：将 Alcohol 列离散化为 3 个区间
df['Alcohol'] = pd.qcut(df['Alcohol'], q=3, labels=['Low', 'Medium', 'High'])

# 将类别变量转换为二进制特征
df_binary = pd.get_dummies(df[['Class', 'Alcohol']], drop_first=True)


# 计算支持度
def calculate_support(itemset, df):
    return df[list(itemset)].min(axis=1).mean()


# 生成频繁项集
def apriori(df, min_support):
    itemsets = {}

    # 计算单个商品的支持度
    for col in df.columns:
        support = calculate_support([col], df)
        if support >= min_support:
            itemsets[frozenset([col])] = support

    # 生成 k-项集
    k = 2
    while True:
        candidates = []
        for itemset1 in itemsets.keys():
            for itemset2 in itemsets.keys():
                if len(itemset1.union(itemset2)) == k:
                    candidates.append(itemset1.union(itemset2))

        new_itemsets = {}
        for candidate in candidates:
            support = calculate_support(candidate, df)
            if support >= min_support:
                new_itemsets[candidate] = support

        if not new_itemsets:
            break

        itemsets.update(new_itemsets)
        k += 1

    return itemsets


# 调用 Apriori 算法
min_support_threshold = 0.1  # 调整支持度阈值
frequent_itemsets = apriori(df_binary, min_support_threshold)

# 输出频繁项集
print("频繁项集及其支持度:")
for itemset, support in frequent_itemsets.items():
    print(f"项集: {set(itemset)}, 支持度: {support:.2f}")